import axios, { type AxiosInstance, type AxiosRequestConfig } from 'axios'; //引入 axios 库（网络请求）
import { NetworkError, BusinessError } from '@/utils/error'; //引入自定义异常处理部分

/**
 * 基于 axios 封装的 HTTP 客户端
 */
const axiosHttp: AxiosInstance = axios.create({
  baseURL: process.env.VITE_APP_API_URL, //服务端接口
  timeout: 10000, // 10 秒超时
  headers: {
    'Content-Type': 'application/json;charset=utf-8', //基础请求头
  },
});
/**
 * 服务端接口通用请求响应数据类型定义
 */

/**
 * 接口响应数据结构(全部)
 */
export interface BaseResponse<T = any> {
  code: number; //状态码
  message: string; //状态信息
  timestamp: number;
  biz_content: BizResponse<T> | BizPagesResponse<T> | null;
}
/**
 * 接口响应业务部分数据结构(业务)
 */
export interface BizResponse<T = any> {
  sub_code: number; //状态码
  sub_message: string; //状态信息
  records: T | null;
}
/**
 * 接口响应业务部分(分页)数据结构(业务)
 */
export interface BizPagesResponse<T = any> {
  sub_code: number; //状态码
  sub_message: string; //状态信息
  current_page: number; //当前页码
  page_size: number; //每页数量
  total_records: number; //总记录数
  records: T | null;
}
/* token 请求头 */
export const TOKEN_HEADER = 'Authorization';
let token: string | null;

/**
 * 请求拦截器
 */
axiosHttp.interceptors.request.use(
  (config) => {
    if (token) {
      config.headers[TOKEN_HEADER] = 'Bearer ' + token;
    } else {
      delete config.headers[TOKEN_HEADER];
    }
    return config;
  },
  (error) => {
    // 抛出错误，未处理
    return Promise.reject(error);
  }
);

/**
 * 响应拦截器
 */
axiosHttp.interceptors.response.use(
  (response) => {
    // 根据content-type ，判断是否为 json 数据
    let contentType = response.headers['content-type'] ? response.headers['content-type'] : response.headers['Content-Type'];
    if (contentType.indexOf('application/json') === -1) {
      return Promise.resolve(response);
    }

    // 如果是json数据
    if (response.data && response.data instanceof Blob) {
      return Promise.reject(new BusinessError('数据接收异常', 503));
    }
    const res = response.data as BaseResponse;
    // 处理业务异常
    if (res.code !== 200) {
      //接口响应异常，抛出业务异常
      return Promise.reject(new BusinessError(res.message, res.code));
    } else {
      console.log('POST 请求响应数据:', res);
      const bizRes = res.biz_content as BizResponse | BizPagesResponse;
      if (bizRes.sub_code !== 100000) {
        //业务响应异常，抛出业务异常
        return Promise.reject(new BusinessError(bizRes.sub_message, bizRes.sub_code));
      } else {
        console.log('BizResponse业务数据:', bizRes);
        // 返回接口响应(业务)数据
        return Promise.resolve(bizRes as any);
      }
    }
  },
  (error) => {
    // 抛出错误，未处理
    if (!error.response) {
      return Promise.reject(new NetworkError('网络连接已中断', 503, error.config));
    }
    return Promise.reject(error);
  }
);

/**
 * 基础请求方法
 */
const request = (config: AxiosRequestConfig): any => {
  return axiosHttp.request(config);
};

export const Http = {
  setToken: (tokenStr: string | null) => {
    token = tokenStr;
  },
  removeToken: () => {
    token = null;
    delete axiosHttp.defaults.headers[TOKEN_HEADER];
  },
  request: async (url: string, params?: AxiosRequestConfig['params']) => {
    try {
      return await request({
        url,
        method: 'get',
        params,
      });
    } catch (error) {
      throw error; //中断程序执行，向上抛出错误，让调用者处理。
    }
  },

  // 基于 request 方法的风格实现 post 方法
  post: async (url: string, data?: AxiosRequestConfig['data']) => {
    try {
      return await request({
        data,
        url,
        method: 'post',
      });
    } catch (error) {
      throw error; //中断程序执行，向上抛出错误，让调用者处理。
    }
  },
};
